home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1993 / MacHack 1993.toast / MacHack™ 1987-1992 / MacHack™ '90 / Utilities ƒ / MPW Tools ƒ / MakeMake / Source / depend.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-12-10  |  11.9 KB  |  476 lines  |  [TEXT/MPS ]

  1. # include "defs.h"
  2. # include <FCntl.h>
  3. # include <CType.h>
  4.  
  5. static char *cur_input_file = "";    /* For use by findinc() */
  6.  
  7. /*
  8.  * Highest-level routine for tracking down #include files
  9.  * and generating a list of dependencies.  Calls includes()
  10.  * with the given filename as a file to read, the corresponding
  11.  * object filename as the dependent, and the output FILE pointer.
  12.  */
  13. depend (out, file)
  14. FILE *out;        /* Where the output should go    */
  15. char *file;        /* File to be read                */
  16.     {
  17.     int linelen = 0;    /* Number of chars on current output line */
  18.     extern char *obj ();
  19.     
  20.     includes (out, obj (file), file, 0, &linelen);
  21.     }
  22.  
  23. /*
  24.  * Open "file" and look for #include lines.  Follow them up
  25.  * recursively, and output dependency statements as you go.
  26.  */
  27. includes (out, orig, file, num, linelen)
  28. FILE *out;        /* Where the output should go            */
  29. char *orig;        /* The original "dependent" file        */
  30. char *file;        /* File to open and read                */
  31. int num;        /* Number of includes output            */
  32. int *linelen;    /* Number of chars on current output line */
  33.     {
  34.     FILE *f;                /* For reading the file                    */
  35.     char *sfx;                /* Filename suffix                        */
  36.     char *save_cur;            /* For saving and restoring cur_input_file */
  37.     char curfile[LINELEN];    /* For storing cur_input_file            */
  38.     extern char *strrchr();    /* Routine for obtaining file suffixes    */
  39.     
  40.     
  41.     progress ("Reading \"%s\"…\n", file);
  42.     
  43.     /*
  44.      * Get the suffix
  45.      */
  46.     sfx = strrchr (file, '.');
  47.     
  48.     
  49.     /*
  50.      * Open the file for reading
  51.      */
  52.     if ((f = fopen (file, "r")) == NULL)
  53.         {
  54.         OSgoof ("Can't open \"%s\" for reading.\n", file);
  55.         return;
  56.         }
  57.     
  58.     /*
  59.      * Set cur_input_file -- findinc() will use this file's directory
  60.      * prefix (if necessary and if any) to look for any files that this
  61.      * file includes.
  62.      */
  63.     strcpy (curfile, file);
  64.     save_cur = cur_input_file;
  65.     cur_input_file = curfile;
  66.     
  67.     /*
  68.      * Call the appropriate routine to read and parse the file.
  69.      */
  70.     if (strcmp (sfx, ".c") == 0 || strcmp (sfx, ".h") == 0)
  71.         CInc (out, orig, f, num, linelen);
  72.     else if (strcmp (sfx, ".p") == 0)
  73.         PInc (out, orig, f, num, linelen);
  74.     else if (strcmp (sfx, ".r") == 0)
  75.         RInc (out, orig, f, num, linelen);
  76.     else if (strcmp (sfx, ".a") == 0)
  77.         AInc (out, orig, f, num, linelen);
  78.  
  79.     cur_input_file = save_cur;    /* Restore previous value    */        
  80.     fclose (f);
  81.     }
  82.     
  83. AInc (out, orig, f, num, linelen)
  84. FILE *out;        /* Where the output should go            */
  85. char *orig;        /* The original "dependent" file        */
  86. FILE *f;        /* For reading the file                    */
  87. int num;        /* Number of includes already output    */
  88. int *linelen;    /* Number of chars on current output line */
  89.     {
  90.     char buf[LINELEN];        /* For input lines from the file        */
  91.     char *argl[ARGMAX];        /* Holds words from an input line        */
  92.     int count;                /* Number of words in an input line        */
  93.     int incix;                /* Index into argl[]                    */
  94.     char *inc;                /* Pointer to new filename                */
  95.     char *ninc;                /* Another pointer to new filename        */
  96.     bool is_label;            /* TRUE if first char of line isn't blank*/
  97.     extern char *findinc();    /* Routine to search for files            */
  98.     
  99.     /*
  100.      * Read each line of the file
  101.      */
  102.     while (fgets (buf, LINELEN, f) != NULL)
  103.         {
  104.         /* First look for position sensitive label field */
  105.         if (!isspace (buf[0]))
  106.             is_label = TRUE;
  107.         else
  108.             is_label = FALSE;
  109.             
  110.         /*
  111.          * Break the line into space-delimited words
  112.          * and look for #include directives
  113.          */
  114.         count = vector (ARGMAX, argl, buf);
  115.         
  116.         if (argl[0][0] == '*' || argl[0][0] == ';')
  117.             continue;    /* This is a comment line */
  118.  
  119.         /*
  120.          * If there is a label, argl[1] is the directive;
  121.          * else argl[0] is.
  122.          */
  123.         if (is_label || argl[0][ strlen (argl[0])-1 ] == ':')
  124.             incix = 1;
  125.         else
  126.             incix = 0;
  127.         if (strcmp (argl[incix], "INCLUDE") != 0)
  128.             continue;
  129.         incix++;    /* Filename follows the directive */
  130.         
  131.         /*
  132.          * Found an INCLUDE line; argl[incix] is the word
  133.          * containing the filename.  Let
  134.          * inc point to the filename, and trim off surrounding quotes
  135.          * if any.
  136.          */
  137.         inc = argl[incix];
  138.         if (*inc == '\'' && inc[ strlen (inc) - 1] == '\'')
  139.             {
  140.             inc++;
  141.             inc[ strlen (inc) - 1] = EOS;
  142.             }
  143.         
  144.         /*
  145.          * File may be local.  If found, print a dependency line, and
  146.          * recursively examine it for more includes.
  147.          */
  148.         if (exists (inc))
  149.             {
  150.             prdepend (out, orig, inc, num, linelen);
  151.             num++;
  152.             includes (out, orig, inc, num, linelen);
  153.             }
  154.         else
  155.             {
  156.             /*
  157.              * File is not local.  Call findinc() to locate it,
  158.              * and if found, print a dependency line and
  159.              * recursively examine it.
  160.              */
  161.             ninc = findinc (inc, adirlist);
  162.             if (ninc == NULL)
  163.                 goof ("\"%s\": file not found\n", inc);
  164.             else
  165.                 {
  166.                 prdepend (out, orig, ninc, num, linelen);
  167.                 num++;
  168.                 includes (out, orig, ninc, num, linelen);
  169.                 }
  170.             }
  171.         
  172.         /*
  173.          * All done with this line; loop back for another.
  174.          */
  175.         }
  176.     
  177.     /*
  178.      * All done with this file.
  179.      */
  180.     }
  181.  
  182. CInc (out, orig, f, num, linelen)
  183. FILE *out;        /* Where the output should go            */
  184. char *orig;        /* The original "dependent" file        */
  185. FILE *f;        /* For reading the file                    */
  186. int num;        /* Number of includes already output    */
  187. int *linelen;    /* Number of chars on current output line */
  188.     {
  189.     char buf[LINELEN];        /* For input lines from the file        */
  190.     char *argl[ARGMAX];        /* Holds words from an input line        */
  191.     int count;                /* Number of words in an input line        */
  192.     int incix;                /* Index into argl[]                    */
  193.     char *inc;                /* Pointer to new filename                */
  194.     char *delim;            /* Pointer to filename delimiter        */
  195.     extern char *findinc();    /* Routine to search for files            */
  196.     
  197.     /*
  198.      * Read each line of the file
  199.      */
  200.     while (fgets (buf, LINELEN, f) != NULL)
  201.         {
  202.         /*
  203.          * Break the line into space-delimited words
  204.          * and look for #include directives
  205.          */
  206.         count = vector (ARGMAX, argl, buf);
  207.         if (count < 2)
  208.             continue;
  209.         if (strcmp (argl[0], "#include") == 0)
  210.             incix = 1;
  211.         else if (strcmp (argl[0], "#") == 0
  212.               && strcmp (argl[1], "include") == 0)
  213.             incix = 2;
  214.         else
  215.             continue;
  216.         if (incix >= count)
  217.             continue;
  218.         
  219.         /*
  220.          * Found a #include line; argl[incix] is the word
  221.          * containing the filename, either in <brackets>
  222.          * or in "quotes".  Record which delimiter it is, and let
  223.          * inc point to the filename stripped of delimiters.
  224.          */
  225.         delim = argl[incix];
  226.         inc = delim + 1;
  227.         inc[ strlen (inc) - 1 ] = EOS;
  228.         
  229.         if (*delim == '"')
  230.             {
  231.             /*
  232.              * File may be local.  If found, print a dependency line,
  233.              * add it to the list of local include files, and
  234.              * recursively examine it for more #includes.
  235.              *
  236.              * If it is not found locally, pretend that the delimiter
  237.              * was a '<' and move on.
  238.              */
  239.             if (exists (inc))
  240.                 {
  241.                 prdepend (out, orig, inc, num, linelen);
  242.                 add_dot_h (inc);
  243.                 num++;
  244.                 includes (out, orig, inc, num, linelen);
  245.                 }
  246.             else
  247.                 *delim = '<';    /* And fall through */
  248.             }
  249.         
  250.         /*
  251.          * File is not local.  Call findinc() to locate it,
  252.          * and if found, print a dependency line and
  253.          * recursively examine it.
  254.          */
  255.         if (*delim == '<')
  256.             {
  257.             inc = findinc (inc, cdirlist);
  258.             if (inc == NULL)
  259.                 goof ("%s>: file not found\n", argl[incix]);
  260.             else
  261.                 {
  262.                 prdepend (out, orig, inc, num, linelen);
  263.                 num++;
  264.                 includes (out, orig, inc, num, linelen);
  265.                 }
  266.             }
  267.         
  268.         /*
  269.          * All done with this line; loop back for another.
  270.          */
  271.         }
  272.     
  273.     /*
  274.      * All done with this file.
  275.      */
  276.     }
  277.     
  278. PInc (out, orig, f, num, linelen)
  279. FILE *out;        /* Where the output should go            */
  280. char *orig;        /* The original "dependent" file        */
  281. FILE *f;        /* For reading the file                    */
  282. int num;        /* Number of includes already output    */
  283. int *linelen;    /* Number of chars on current output line */
  284.     {
  285.     bool in_uses = FALSE;    /* Stackable data for Pparse()            */
  286.     bool dollar_u = FALSE;    /* Stackable data for Pparse()            */
  287.     char *inc;                /* Pointer to new filename                */
  288.     char *ninc;                /* Another pointer to new filename        */
  289.     extern char *findinc();    /* Routine to search for files            */
  290.     extern char *strchr ();    /* Routine to search a string for a char*/
  291.     extern char *Pparse ();
  292.     
  293.     while ((inc = Pparse (&in_uses, &dollar_u, f)) != NULL)
  294.         {
  295.         /*
  296.          * Found a filename.
  297.          * File may be local.  If found, print a dependency line, and
  298.          * recursively examine it for more includes.
  299.          *
  300.          * If it is not found locally, try findinc().
  301.          */
  302.         if (exists (inc))
  303.             {
  304.             prdepend (out, orig, inc, num, linelen);
  305.             num++;
  306.             includes (out, orig, inc, num, linelen);
  307.             }
  308.         else
  309.             {
  310.             /*
  311.              * File is not local.  Call findinc() to locate it,
  312.              * and if found, print a dependency line and
  313.              * recursively examine it.  (Check first to see if it's
  314.              * a relative pathname.)
  315.              */
  316.             if (*inc == ':' || strchr (inc, ':') == NULL)
  317.                 ninc = findinc (inc, pdirlist);
  318.             else
  319.                 ninc = NULL;
  320.                 
  321.             if (ninc == NULL)
  322.                 goof ("\"%s\": file not found\n", inc);
  323.             else
  324.                 {
  325.                 prdepend (out, orig, ninc, num, linelen);
  326.                 num++;
  327.                 includes (out, orig, ninc, num, linelen);
  328.                 }
  329.             }
  330.         }
  331.     }
  332.     
  333. RInc (out, orig, f, num, linelen)
  334. FILE *out;        /* Where the output should go            */
  335. char *orig;        /* The original "dependent" file        */
  336. FILE *f;        /* For reading the file                    */
  337. int num;        /* Number of includes already output    */
  338. int *linelen;    /* Number of chars on current output line */
  339.     {
  340.     char *inc;                /* Pointer to new filename                */
  341.     char *ninc;                /* Another pointer to new filename        */
  342.     extern char *findinc();    /* Routine to search for files            */
  343.     extern char *strchr ();    /* Routine to search a string for a char*/
  344.     extern char *Rparse ();    /* Routine to parse Rez input files        */
  345.  
  346.     /*
  347.      * Read each line of the file
  348.      */
  349.     while ((inc = Rparse (f)) != NULL)
  350.         {
  351.         /*
  352.          * Found an INCLUDE or READ line.
  353.          * File may be local.  If found, print a dependency line.
  354.          *
  355.          * If it is not found locally, try findinc().
  356.          */
  357.         if (exists (inc))
  358.             prdepend (out, orig, inc, num, linelen);
  359.         else
  360.             {
  361.             /*
  362.              * File is not local.  Call findinc() to locate it,
  363.              * and if found, print a dependency line.
  364.              */
  365.             if (*inc == ':' || strchr (inc, ':') == NULL)
  366.                 ninc = findinc (inc, rdirlist);
  367.             else
  368.                 ninc = NULL;
  369.                 
  370.             if (ninc == NULL)
  371.                 goof ("\"%s\": file not found\n", inc);
  372.             else
  373.                 prdepend (out, orig, ninc, num, linelen);
  374.             }
  375.         
  376.         /*
  377.          * All done with this line; loop back for another.
  378.          */
  379.         }
  380.     
  381.     /*
  382.      * All done with this file.
  383.      */
  384.     }
  385.  
  386. /*
  387.  * Search for the given filename in the list of include directories.
  388.  * Return a pointer to the full pathname, or NULL if not found.
  389.  */
  390. char *findinc (file, list)
  391. char *file;            /* Filename                        */
  392. char **list[];        /* List of include directories    */
  393.     {
  394.     int i;                            /* Loop counter            */
  395.     char *p;                        /* Temp pointer            */
  396.     int flen = strlen (file);        /* Length of filename    */
  397.     static char buf[LINELEN];        /* Buffer for pathname    */
  398.     extern bool exists ();
  399.  
  400.     /*
  401.      * Skip a leading colon, if any.
  402.      */
  403.     if (*file == ':')
  404.         {
  405.         file++;
  406.         flen--;
  407.         }
  408.     
  409.     /*
  410.      * Check in the directory of the current input file.
  411.      */
  412.     strcpy (buf, cur_input_file);
  413.     if ((p = strrchr (buf, ':')) != NULL)
  414.         {
  415.         p++;
  416.         *p = EOS;
  417.         if (strlen (buf) > LINELEN - (flen + 1))
  418.             {
  419.             goof ("Search path too long: \"%s%s\"\n",
  420.                 buf, file);
  421.             return (NULL);
  422.             }
  423.         strcat (buf, file);
  424.         if (exists (buf))
  425.             return (buf);
  426.         }
  427.     
  428.     /*
  429.      * For each search directory, construct a pathname and see if the
  430.      * file is there.  Return the path if so.
  431.      */
  432.     for (i = 0; i < DIRMAX && list[i] != NULL; i++)
  433.         {
  434.         if (strlen (list[i]) > LINELEN - (flen + 1))
  435.             {
  436.             goof ("Search path too long: \"%s%s\"\n",
  437.                 list[i], file);
  438.             return (NULL);
  439.             }
  440.         strcpy (buf, list[i]);
  441.         strcat (buf, file);
  442.         if (exists (buf))
  443.             return (buf);
  444.         }
  445.     
  446.     /*
  447.      * Nowhere to be found.
  448.      */
  449.     return (NULL);
  450.     }
  451.  
  452. prdepend (out, orig, inc, num, linelen)
  453. FILE *out;        /* Where the output should go            */
  454. char *orig;        /* The original "dependent" file        */
  455. char *inc;        /* The dependency (included) file        */
  456. int num;        /* Number of includes output            */
  457. int *linelen;    /* Number of chars on current output line */
  458.     {
  459. # define PRETTYLINELEN    50
  460.     if (num == 0)
  461.         {
  462.         fprintf (out, "%s ƒ %s", orig, inc);
  463.         *linelen = strlen (orig) + strlen (inc) + 3;
  464.         }
  465.     else
  466.         {
  467.         if (*linelen > PRETTYLINELEN)
  468.             {
  469.             fprintf (out, " ∂\n\t");
  470.             *linelen = 4;    /* For the tab */
  471.             }
  472.         fprintf (out, " %s", inc);
  473.         *linelen += strlen (inc) + 1;
  474.         }
  475.     }
  476.